/* 
 * Nome do Projeto: CPE
 * Nome da Classe : TransactionFilter.java
 * Data de Criação: 03/03/2010
 * 
 * 
 * HISTÓRICO DE MUDANÇAS:
 * =====================================================================
 * ####        Jefferson Amorim (jefferson.amorim@tjpe.jus.br)
 * 03/03/2010  Inclusão de comentários
 * =====================================================================
 */
package br.iars.web.filter;

import java.io.IOException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.transaction.Status;
import javax.transaction.UserTransaction;

import org.apache.log4j.Logger;

public class TransactionFilter implements Filter {

    /**
     * Logger for the class
     */
    private final static Logger logger = Logger.getLogger(TransactionFilter.class);

    /**
     * @param request
     *            The request that we serve
     * @param response
     *            The response that we create
     * @param chain
     *            The chain of other filters that may have been defined
     * @throws IOException
     *             wraps any I/O related exception thrown during processing
     * @throws ServletException
     *             wraps any exception thrown during processing
     */
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
            ServletException {
        if (request instanceof HttpServletRequest) {
            UserTransaction utx = null;
            try {
                Context ctx = new InitialContext();
                Object ref = ctx.lookup("UserTransaction");
                utx = (UserTransaction) PortableRemoteObject.narrow(ref, UserTransaction.class);
//                utx = (UserTransaction) ref;
                utx.begin();
                chain.doFilter(request, response);
                int status = utx.getStatus();
                if (status == Status.STATUS_ACTIVE)
                    utx.commit();
                else
                    utx.rollback();
            } catch (Throwable e) {
                try {
                    if ((utx != null) && (utx.getStatus() == Status.STATUS_ACTIVE))
                        utx.rollback();
                } catch (Throwable e1) {
                    logger.error("Cannot rollback transaction", e1);
                }
                if (e instanceof ServletException)
                    throw (ServletException) e;
                if (e instanceof IOException)
                    throw (IOException) e;
                if (e instanceof RuntimeException)
                    throw (RuntimeException) e;
                throw new ServletException(e);
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    public void destroy() {
    }

    /**
     * {@inheritDoc}
     */
    public void init(FilterConfig arg0) throws ServletException {
    }
}